#include "serial_widget.h"
#include "ui_serial_widget.h"

SerialWidget::SerialWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SerialWidget)
{
    ui->setupUi(this);
    this->recv_file = new QFile(this);
    ui->plainTextEdit_send->installEventFilter(this);
}

SerialWidget::~SerialWidget()
{
    this->recv_file->close();
    delete this->recv_file;
    delete ui;
}

void SerialWidget::setSerialPort(QSerialPort* serialPort){
    this->m_serialPort = serialPort;
    ui->label_name->setText(serialPort->portName());
    ui->label_baud->setText(QString("Baud:%1").arg(serialPort->baudRate()));
    ui->label_parity->setText(  QString("Parity:   %1").arg(serialPort->parity()));
    ui->label_databits->setText(QString("Data Bits:%1").arg(serialPort->dataBits()));
    ui->label_stopbits->setText(QString("Stop Bits:%1").arg(serialPort->stopBits()));

    connect(m_serialPort, &QSerialPort::readyRead, this, [=]{
        QByteArray data = m_serialPort->readAll();
        if (ui->checkBox_hex_show->isChecked()){
            data = data.toHex(':');
        }
        ui->plainTextEdit_recv->insertPlainText(data);
        if (ui->checkBox_recv_to_file->isChecked()) {
            this->recv_file->write(data);
        }
    });
}

bool SerialWidget::eventFilter(QObject *object, QEvent *event)
{
    if( event->type() == QEvent::KeyPress) {

    if (object == ui->plainTextEdit_send && ui->checkBox_hex_send->isChecked()){
            QKeyEvent* e = static_cast<QKeyEvent*>(event);

            if (e->key() == Qt::Key_Backspace
                    || (e->key()>=Qt::Key_Home && e->key()<=Qt::Key_Down)
                    || e->key()==Qt::Key_Space) {
                return false;
            }
            if (ui->plainTextEdit_send->toPlainText().length()%3 == 2){
                ui->plainTextEdit_send->insertPlainText(" ");
            }
            if (e->key()>=Qt::Key_0 && e->key()<=Qt::Key_9)
                return false;
            if (e->key()>=Qt::Key_A && e->key()<=Qt::Key_F)
                return false;
            if (e->key() == Qt::Key_Return && (e->modifiers() & Qt::ShiftModifier)){
                send();
                return true;
            }
            return true;
        }
    }
    return false;
}

void SerialWidget::send()
{
    QByteArray dat = ui->plainTextEdit_send->toPlainText().toLocal8Bit();

    QByteArray dat_for_send = dat;
    if (ui->checkBox_hex_send->isChecked()) {
        dat_for_send = QByteArray::fromHex(dat);
    }
    this->m_serialPort->write(dat_for_send);
}
void SerialWidget::on_pushButton_send_clicked()
{
    send();
}

void SerialWidget::on_pushButton_disconnect_clicked()
{
    if (this->m_serialPort->isOpen()) {
        this->m_serialPort->close();
        ui->pushButton_disconnect->setText("connect");
    }
    else {
        this->m_serialPort->open(QSerialPort::ReadWrite);
        ui->pushButton_disconnect->setText("disconnect");
    }
}

void SerialWidget::on_pushButton_save_to_file_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
                                QDir::homePath()+"/data.dat",
                                tr("Bin (*.bin *.dat)"));
    if (fileName.length() > 0){
        QFile file(fileName);
        if (file.open(QFile::ReadWrite)) {
            file.write(ui->plainTextEdit_recv->toPlainText().toLocal8Bit());
            file.close();
        }
        else {
            QMessageBox::warning(this, "open file failed", file.errorString());
        }
    }
}

void SerialWidget::on_checkBox_recv_to_file_stateChanged(int arg1)
{
    if (arg1 == Qt::Checked){
        QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
                                                        QDir::homePath()+"/data.dat",
                                                        tr("Bin (*.bin *.dat)"));
        if (fileName.length() > 0){
            this->recv_file->setFileName(fileName);
        }
    }
    else {
        this->recv_file->close();
    }
}
